﻿using System;
using Needle.Utils;

namespace Needle.Framework
{
    /// <summary>
    /// 
    /// </summary>
    public class LifetimeComponent : Component, INotifyLifetime
    {
        #region IInitializeNotification Members
        private static readonly object InitializedKey = new object();
        /// <summary>
        /// Raised when the component has been initialized.
        /// </summary>
        public event EventHandler Initialized
        {
            add { Events.AddHandler(InitializedKey,value); }
            remove { Events.RemoveHandler(InitializedKey, value); }
        }

        private bool _IsInitialized;
        /// <summary>
        /// True when the component has been initialized;
        /// </summary>
        public bool IsInitialized
        {
            get { return _IsInitialized; }
        }

        #endregion

        #region IInitializable Members

        private bool _initializing;

        /// <summary>
        /// Starts initialization
        /// </summary>
        public virtual void BeginInit()
        {
            Ensure.ValidOperation(!_initializing,"Already initializing.");
            Ensure.ValidOperation(!IsInitialized,"Already initialized.");
            _initializing = true;
        }
        /// <summary>
        /// Ends initialization.
        /// </summary>
        public virtual void EndInit()
        {
             Ensure.ValidOperation(_initializing, "Call BeginInit first.");
             Ensure.ValidOperation(!_IsInitialized, "Already initialized.");
            _IsInitialized = true;
            _initializing = false;
            OnInitialized();
        }

        /// <summary>
        /// Calls BeginInit() and EndInit().
        /// </summary>
        public void Initialize()
        {
            BeginInit();
            EndInit();
        }

        private void OnInitialized()
        {
            EventHandler handler = Events[InitializedKey] as EventHandler;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }
        #endregion
    }
}
